package com.woniuxy.service.impl;

import com.woniuxy.entity.Book;
import com.woniuxy.mapper.BookMapper;
import com.woniuxy.service.BookService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author ：CuiYC
 * @description：
 * @date ：Created in 2025/3/7 16:31
 * @modified By：
 */
@Service
//@AllArgsConstructor //生成全参构造，Spring注入的方式 1：set 2：属性注入 3：构造器注入（官方推荐）
public class BookServiceImpl implements BookService {

    @Resource
    private BookMapper bookMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplateInit; //默认RedisTemplate<Object, Object>
//    private StringRedisTemplate redisTemplate; == RedisTemplate<String,String> redisTemplate;


    ReentrantLock reentrantLock = new ReentrantLock();
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Override
    public List<Book> queryAll() {
        return bookMapper.queryAll();
    }

    /**
     * 给接口数据做缓存
     * @param id
     * @return
     * 缓存穿透
     * 定义
     * 解决方案
     *      缓存空对象
     *          缺点：保存很多垃圾数据，浪费内存
     *          优点：简单
     *      布隆过滤器：底层是采用redis的bitmap数据类型实现的一门技术
     *                   bitmap是一个很长的二进制数据
     *         布隆过滤器判定没有的一定没有，判定有的可能有，即存在一定误判率。
     *                  误判率可控，但需要牺牲性能。
                 * 缺点：误判
                 * 优点：用布隆过滤器判断数据是否存在，仅使用了bit标识，节约空间。
     *
     * redis的五种基本类型
     *      String, hash, set, zset, list
     */
    @Override
    public Book queryBookById(Integer id) {
        // 先从redis中尝试获取数据
        try {
            Book catchBook = (Book) redisTemplateInit.opsForHash().get("CACHE:BOOKSERVICEIMPL:QUERYBOOKBYID", id+"");
            if (catchBook != null) {
                return catchBook;
            }

            //加锁
            boolean b = reentrantLock.tryLock();

            if (b) {
                Book book = bookMapper.queryBookById(id);
                //把book书籍存入redis
                redisTemplateInit.opsForHash().put("CACHE:BOOKSERVICEIMPL:QUERYBOOKBYID", id+"",
                        book == null ? new Book() : book);
                return book;
            }else{
                //没获取到锁
                return null;
            }
        } finally {
            if (reentrantLock.isHeldByCurrentThread() && reentrantLock.isLocked() ) {
                reentrantLock.unlock(); //当前线程只能释放当前线程锁
            }
        }

    }
//    /**
//     * 延迟双删
//     */
//    public void updateBook(Book book) throws InterruptedException {
//        //1.删除缓存
//        redisTemplate.delete("key");
//        //2.更新数据库
//        bookMapper.updateBook(book);
//        //3.延迟，这里的时间要保证查询方法执行完，且不得延迟大于1s
//        Thread.sleep(200);
//        //4.再删除缓存
//        redisTemplate.delete("key");
//    }
}
